package han.tn.hanlibs_cachefile;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.PrintWriter;

import android.content.Context;
import android.os.Environment;

public class CacheFile {
	private static final String TAG = "HanLibs_CacheFile";

	/**
	 * 
	 * @param pathToSaveFile
	 *            : Path to save file ( without the / character at the begin of
	 *            path (Ex: yourapp/data/)
	 * @param fileName
	 *            : fileName
	 * @param isSaveInExternalStorage
	 *            : If not set, the default will be External and if device has
	 *            no SDCard, this will be save to Internal Storage
	 */
	public static boolean saveFile(Context context, String fileName,
			String pathToSaveFile, String content) {
		boolean mExternalStorageAvailable = false;
		boolean mExternalStorageWriteable = false;
		String mState = Environment.getExternalStorageState();

		if (Environment.MEDIA_MOUNTED.equals(mState)) {
			// We can read and write the media
			mExternalStorageAvailable = mExternalStorageWriteable = true;
		} else if (Environment.MEDIA_MOUNTED_READ_ONLY.equals(mState)) {
			// We can only read the media
			mExternalStorageAvailable = true;
			mExternalStorageWriteable = false;
		} else {
			// Something else is wrong. It may be one of many other states,
			// but all we need
			// to know is we can neither read nor write
			mExternalStorageAvailable = mExternalStorageWriteable = false;
		}
		if (mExternalStorageAvailable == true
				&& mExternalStorageWriteable == true) {
			// User External
			File root = Environment.getExternalStorageDirectory();
			File dir = new File(root.getAbsolutePath() + "/" + pathToSaveFile);
			dir.mkdirs();
			File file = new File(dir, fileName);
			try {
				FileOutputStream f = new FileOutputStream(file);
				PrintWriter pw = new PrintWriter(f);
				pw.println(content);
				pw.flush();
				pw.close();
				f.close();
				return true;
			} catch (FileNotFoundException e) {
				// Use Internal
				FileOutputStream fos;
				try {
					fos = context
							.openFileOutput(fileName, Context.MODE_PRIVATE);
					fos.write(content.getBytes());
					fos.close();
					return true;
				} catch (FileNotFoundException e1) {
					// TODO Auto-generated catch block
					e1.printStackTrace();
					return false;
				} catch (IOException e1) {
					// TODO Auto-generated catch block
					e1.printStackTrace();
					return false;
				}
			} catch (IOException e) {
				// Use Internal
				FileOutputStream fos;
				try {
					fos = context
							.openFileOutput(fileName, Context.MODE_PRIVATE);
					fos.write(content.getBytes());
					fos.close();
					return true;
				} catch (FileNotFoundException e1) {
					// TODO Auto-generated catch block
					e1.printStackTrace();
					return false;
				} catch (IOException e1) {
					// TODO Auto-generated catch block
					e1.printStackTrace();
					return false;
				}
			}
		} else {
			// Use Internal
			try {
				FileOutputStream fos = context.openFileOutput(fileName,
						Context.MODE_PRIVATE);
				fos.write(content.getBytes());
				fos.close();
				return true;
			} catch (FileNotFoundException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
				return false;
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
				return false;
			}

		}
	}

	/**
	 * 
	 * @param context
	 * @param fileName
	 * @param pathToSaveFile
	 * @return content of file or null if file does not exist
	 */
	public static String readFile(Context context, String fileName,
			String pathToSaveFile) {
		String mContent = "";
		boolean mExternalStorageAvailable = false;
		boolean mExternalStorageWriteable = false;
		String mState = Environment.getExternalStorageState();

		if (Environment.MEDIA_MOUNTED.equals(mState)) {
			// We can read and write the media
			mExternalStorageAvailable = mExternalStorageWriteable = true;
		} else if (Environment.MEDIA_MOUNTED_READ_ONLY.equals(mState)) {
			// We can only read the media
			mExternalStorageAvailable = true;
			mExternalStorageWriteable = false;
		} else {
			// Something else is wrong. It may be one of many other states,
			// but all we need
			// to know is we can neither read nor write
			mExternalStorageAvailable = mExternalStorageWriteable = false;
		}
		if (mExternalStorageAvailable == true
				&& mExternalStorageWriteable == true) {
			File root = new File(Environment.getExternalStorageDirectory()
					.getAbsolutePath() + "/" + pathToSaveFile, fileName);
			try {
				@SuppressWarnings("resource")
				BufferedReader reader = new BufferedReader(
						new InputStreamReader(new FileInputStream(root)));
				StringBuffer stringBuff = new StringBuffer();
				while ((mContent = reader.readLine()) != null) {
					stringBuff.append(mContent + "\n");
				}
				mContent = stringBuff.toString();
			} catch (FileNotFoundException e) {
				// Read from Internal
				try {
					InputStream inputStream = context.openFileInput(fileName);
					if (inputStream != null) {
						InputStreamReader inputStreamReader = new InputStreamReader(
								inputStream);
						BufferedReader bufferReader = new BufferedReader(
								inputStreamReader);
						String receiveString = "";
						StringBuilder stringBuilder = new StringBuilder();
						while ((receiveString = bufferReader.readLine()) != null) {
							stringBuilder.append(receiveString);
						}
						inputStream.close();
						mContent = stringBuilder.toString();
					}
				} catch (FileNotFoundException ea) {
					// TODO Auto-generated catch block
					e.printStackTrace();
					return null;
				} catch (IOException ea) {
					// TODO Auto-generated catch block
					e.printStackTrace();
					return null;
				}
			} catch (IOException e) {
				// Read from Internal
				try {
					InputStream inputStream = context.openFileInput(fileName);
					if (inputStream != null) {
						InputStreamReader inputStreamReader = new InputStreamReader(
								inputStream);
						BufferedReader bufferReader = new BufferedReader(
								inputStreamReader);
						String receiveString = "";
						StringBuilder stringBuilder = new StringBuilder();
						while ((receiveString = bufferReader.readLine()) != null) {
							stringBuilder.append(receiveString);
						}
						inputStream.close();
						mContent = stringBuilder.toString();
					}
				} catch (FileNotFoundException es) {
					// TODO Auto-generated catch block
					e.printStackTrace();
					return null;
				} catch (IOException es) {
					// TODO Auto-generated catch block
					e.printStackTrace();
					return null;
				}
			}
		} else {
			// Read from Internal
			try {
				InputStream inputStream = context.openFileInput(fileName);
				if (inputStream != null) {
					InputStreamReader inputStreamReader = new InputStreamReader(
							inputStream);
					BufferedReader bufferReader = new BufferedReader(
							inputStreamReader);
					String receiveString = "";
					StringBuilder stringBuilder = new StringBuilder();
					while ((receiveString = bufferReader.readLine()) != null) {
						stringBuilder.append(receiveString);
					}
					inputStream.close();
					mContent = stringBuilder.toString();
				}
			} catch (FileNotFoundException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
				return null;
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
				return null;
			}

		}
		return mContent;
	}

	public static boolean deleteCache(Context context, String mPath) {
		boolean mExternalStorageAvailable = false;
		boolean mExternalStorageWriteable = false;
		String mState = Environment.getExternalStorageState();

		if (Environment.MEDIA_MOUNTED.equals(mState)) {
			// We can read and write the media
			mExternalStorageAvailable = mExternalStorageWriteable = true;
		} else if (Environment.MEDIA_MOUNTED_READ_ONLY.equals(mState)) {
			// We can only read the media
			mExternalStorageAvailable = true;
			mExternalStorageWriteable = false;
		} else {
			// Something else is wrong. It may be one of many other states,
			// but all we need
			// to know is we can neither read nor write
			mExternalStorageAvailable = mExternalStorageWriteable = false;
		}
		if (mExternalStorageAvailable == true
				&& mExternalStorageWriteable == true) {
			File path = new File(Environment.getExternalStorageDirectory()
					.getAbsolutePath() + "/" + mPath);
			boolean b = deleteDirectory(context, path);
			if (b == false) {
				path = context.getFilesDir();
				return deleteDirectory(context, path);
			}
			return b;
		} else {
			File path = context.getFilesDir();
			return deleteDirectory(context, path);
		}
	}

	private static boolean deleteDirectory(Context context, File path) {

		// check if path exists
		if (path.exists()) {

			// is directory
			if (path.isDirectory()) {

				// get list of file in directory
				File[] files = path.listFiles();
				for (int i = 0; i < files.length; i++) {

					// if it a directory make recursive call
					// to deleteFile method
					if (files[i].isDirectory()) {
						deleteDirectory(context, files[i]);
					} else {
						// delete actual file
						files[i].delete();
					}
				}
			}
		}
		// finally delete the path
		return (path.delete());
	}
}
